package com.woniuxy.microloanserver.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.bean.MemberEntity;
import com.woniuxy.bean.ResultBean;
import com.woniuxy.bean.SysRateBean;
import com.woniuxy.bean.regularbean.MemberAccountOutBean;
import com.woniuxy.constant.SysRateConst;
import com.woniuxy.microloanserver.bean.LoanOrderBean;
import com.woniuxy.microloanserver.bean.UserLoanInterestRateBean;
import com.woniuxy.microloanserver.bean.UserLoanQuotaInfo;
import com.woniuxy.microloanserver.constant.LoanQuotaConst;
import com.woniuxy.microloanserver.feign.SysFeign;
import com.woniuxy.microloanserver.feign.SystemFeign;
import com.woniuxy.microloanserver.service.UserQuotaService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Description: 用户贷款额度相关业务控制层
 *
 * @Auther: HanLei
 * @Date: 2021/4/16:9:34
 */
@RefreshScope
@Slf4j
@Api(tags = "用户贷款额度相关接口")
@RestController
@RequestMapping(value = "/loan/quota", produces = {"application/json;charset=utf-8"})
public class UserQuotaController {

    @Resource(name = "redisTemplate")
    ValueOperations<String, Object> valueOperations;
    @Resource
    private SysFeign sysFeign;
    @Resource
    private SystemFeign systemFeign;
    @Resource
    private UserQuotaService userQuotaServiceImpl;
    @Resource
    private final ObjectMapper om = new ObjectMapper();

    /*
     * Description : 根据用户id获取用户贷款额度相关信息
     * ChangeLog : 1. 创建 (2021/4/16 9:37 );
     * @param userId    用户id
     * @return String   JSON字符串
     */
    @ApiOperation("查询用户贷款额度")
    @PostMapping("/getQuota")
    public ResultBean getUserQuota (@ApiParam(value = "用户ID", required = true) @RequestBody LoanOrderBean loanOrderBean) {
        try {
            UserLoanQuotaInfo userLoanQuota = userQuotaServiceImpl.getUserLoanQuota(loanOrderBean.getFkUserId());
            if (userLoanQuota == null) {
                return ResultBean.builder().code(400).msg("暂无额度！").build();
            } else {
                //获取分期服务费率
                BigDecimal instalmentServiceRate = updateSysRate();
                if (instalmentServiceRate != null) {
                    userLoanQuota.setInstalmentService(instalmentServiceRate);
                    return ResultBean.builder().code(200).msg("查询成功！").data(userLoanQuota).build();
                } else {
                    return ResultBean.builder().code(500).msg("服务器繁忙，请稍后重试！").build();
                }
            }
        } catch (Exception e) {
            return ResultBean.builder().code(500).msg("服务器繁忙，请稍后重试！").build();
        }
    }

    /*
     * Description :   申请额度；根据用户资料、个人资产（不包括钱包余额）审批
     * ChangeLog : 1. 创建 (2021/4/16 11:53 );
     * @param userName    用户名
     * @return String   JSON字符串
     */
    @ApiOperation("申请贷款额度")
    @PostMapping("/applyQuota")
    public ResultBean applyQuota (@ApiParam(value = "用户名", required = true) @RequestBody LoanOrderBean loanOrderBean) {
        try {
            MemberEntity member = new MemberEntity();//getMemberInfo方法的参数
            member.setUsername(loanOrderBean.getUserName());
            //获取用户信息
            String memberInfo = sysFeign.getMemberInfo(member);

            MemberEntity memberEntity = JSON.parseObject(
                    JSON.parseObject(memberInfo).getString("data"), MemberEntity.class);//用户资料
            HashMap<String, Object> userInfoMap = null;
            if (memberEntity != null) {
                //调用贷款资质审核
                userInfoMap = getUserInfo(memberEntity);
                int userId = memberEntity.getId();
                UserLoanQuotaInfo userLoanQuota = userQuotaServiceImpl.getUserLoanQuota(userId);
                //判断用户是否已有额度
                if (userLoanQuota != null) {
                    return ResultBean.builder().code(400).msg("请勿重复申请！").build();
                }
            }
            //判断该用户是否通过系统审核
            UserLoanQuotaInfo userLoanQuotaInfo = null;
            BigDecimal totalQuota = null;
            if (userInfoMap != null) {
                //调用贷款额度审核
                totalQuota = examineQuota(userInfoMap);
            } else {
                return ResultBean.builder().code(400).msg("对不起，经系统评估您暂时不具备贷款资质！").build();
            }

            //判断是否获得额度
            if (totalQuota != null) {
                //获取分期服务费
                BigDecimal instalmentServiceRate = updateSysRate();
                if (instalmentServiceRate == null) {
                    return ResultBean.builder().code(400).msg("系统异常，请稍后重试！").build();
                }
                //用户贷款利率对象
                UserLoanInterestRateBean interestRateBean = new UserLoanInterestRateBean();
                interestRateBean.setUserId((Integer) userInfoMap.get(LoanQuotaConst.UserInfoKey.USER_ID));
                interestRateBean.setDaily(LoanQuotaConst.InterestRateValue.DAILY_DEFAULT);
                interestRateBean.setThree(LoanQuotaConst.InterestRateValue.THREE_TIMES_DEFAULT);
                interestRateBean.setSix(LoanQuotaConst.InterestRateValue.SIX_TIMES_DEFAULT);
                interestRateBean.setNine(LoanQuotaConst.InterestRateValue.NINE_TIMES_DEFAULT);
                interestRateBean.setTwelve(LoanQuotaConst.InterestRateValue.TWELVE_TIMES_DEFAULT);
                //为用户贷款额度信息对象赋值
                userLoanQuotaInfo = new UserLoanQuotaInfo();
                userLoanQuotaInfo.setUserId((Integer) userInfoMap.get(LoanQuotaConst.UserInfoKey.USER_ID));//用户id
                userLoanQuotaInfo.setTotalQuota(totalQuota);//总额度
                userLoanQuotaInfo.setUserLoanInterestRate(interestRateBean);//袋款利率
                userLoanQuotaInfo.setInstalmentService(instalmentServiceRate);//分期服务费

                //将其存入数据库并转化为JSON字符串返回
                userQuotaServiceImpl.addQuota(userLoanQuotaInfo);
                userQuotaServiceImpl.addUserRate(userLoanQuotaInfo.getUserLoanInterestRate());
                return ResultBean.builder().code(200).msg("申请成功！").data(userLoanQuotaInfo).build();
            } else {
                return ResultBean.builder().code(400).msg("对不起，你暂时未获得贷款额度！").build();
            }
        } catch (Exception e) {
            log.error("评估失败：{}", e);
            return ResultBean.builder().code(400).msg("评估失败，请稍后再试！").build();
        }
    }

    /*
     * Description :   申请提升额读
     * ChangeLog : 1. 创建 (2021/4/17 16:08 );
     * @param null
     * @return null
     */
    @ApiOperation("申请提升额度")
    @PostMapping("/applyQuotaUp")
    public ResultBean promoteQuota (@ApiParam(value = "对象", required = true) @RequestBody LoanOrderBean loanOrderBean) {

        try {
            UserLoanQuotaInfo userLoanQuota = userQuotaServiceImpl.getUserLoanQuota(loanOrderBean.getFkUserId());//用户贷款额度对象
            MemberEntity memberEntity = null;//用户资料
            HashMap<String, Object> userInfoMap = null;//用户贷款额度影响因子集合
            BigDecimal newQuota = null; //新额度
            UserLoanQuotaInfo newUserLoanQuota = null;//新用户贷款额度对象
            //判断该用户是否拥有额度
            if (userLoanQuota != null) {
                MemberEntity member = new MemberEntity();//getMemberInfo方法的参数
                member.setUsername(loanOrderBean.getUserName());
                //获取用户信息
                String memberInfo = sysFeign.getMemberInfo(member);
                memberEntity = JSON.parseObject(
                        JSON.parseObject(memberInfo).getString("data"), MemberEntity.class);//用户资料
            } else {
                return ResultBean.builder().code(400).msg("对不起，您暂时没有提额资格！").build();
            }

            //调用贷款资质审核
            if (memberEntity != null) {
                userInfoMap = getUserInfo(memberEntity);
            }

            //判断该用户是否通过系统审核
            if (userInfoMap != null) {
                //调用贷款额度审核
                newQuota = examineQuota(userInfoMap);
            } else {
                return ResultBean.builder().code(400).msg("对不起，您暂时没有提额资格！").build();
            }

            int isGreaterThanNow = 0; //新额度是否大于现有额度
            int isGreaterThanMax = 0; //新额度是否大于最大额度
            //判断是否获取新额度
            if (newQuota != null) {
                BigDecimal nowQuota = userLoanQuota.getTotalQuota();//现有额度
                isGreaterThanNow = newQuota.compareTo(nowQuota);//新额度在数字上小于、等于或大于 现有额度 时，返回 -1、0 或 1。
            } else {
                return ResultBean.builder().code(400).msg("提额失败，请保持良好的信用！").build();
            }

            //判断新额度是否大于现有额度
            if (isGreaterThanNow == 1) {
                newUserLoanQuota = new UserLoanQuotaInfo();
                newUserLoanQuota.setUserId(loanOrderBean.getFkUserId());
                isGreaterThanMax = newQuota.compareTo(LoanQuotaConst.LoanQuotaValue.LOAN_QUOTA_MAX);
                //判断新额度是否大于最大额度
                if (isGreaterThanMax == 1) {
                    newQuota = LoanQuotaConst.LoanQuotaValue.LOAN_QUOTA_MAX;//新额度大于最大额度，使用最大额度将新额度覆盖
                }
                newUserLoanQuota.setTotalQuota(newQuota);
                userQuotaServiceImpl.update(newUserLoanQuota);
                return ResultBean.builder().code(200).msg("提额成功！").data(newQuota).build();
            } else {
                return ResultBean.builder().code(400).msg("提额失败，请保持良好的信用！").build();
            }
        } catch (Exception e) {
            log.error("提额异常：{}", e.getMessage());
            return ResultBean.builder().code(401).msg("服务器繁忙，请稍后重试！").build();
        }
    }


    /*
     * Description :   用户贷款资质审核
     * ChangeLog : 1. 创建 (2021/4/16 16:52 );
     * @param userName  用户名
     * @return userInfoMap  用户贷款额度审核的影响因子集合（实名、信用等级、总资产）
     */
    private HashMap<String, Object> getUserInfo (MemberEntity memberEntity) {
        HashMap<String, Object> userInfoMap = null;//用于封装用户贷款额度审核的影响因子
        try {

            //获取个人资产信息
            String assets = sysFeign.getAssets(memberEntity);
//            String assets = "{ \"code\": 200,\n" +
//                    "                    \"data\": {\n" +
//                    "                \"sumEarnings\": 0,\n" +
//                    "                        \"sumOverAllBalance\": 10000.19,\n" +
//                    "                        \"todaySumEarnings\": 0\n" +
//                    "            },\n" +
//                    "                \"msg\": \"查询成功\"\n" +
//                    "            }";
            MemberAccountOutBean memberAccountOutBean = JSON.parseObject(
                    JSON.parseObject(assets).getString("data"), MemberAccountOutBean.class);//个人资产
            double totalAssets = memberAccountOutBean.getSumOverAllBalance();//个人总资产
            int risk = memberEntity.getRisk();//信用分
            //实名信息
            if ("".equals(memberEntity.getIdcard()) || memberEntity.getIdcard() == null) {
                return null;
                //年龄必须大于24
//            } else if (risk < LoanQuotaConst.CriteriaValue.RISK_MIN) {
//                return null;
//                //个人资产必须大于0
//            } else if (! (totalAssets > LoanQuotaConst.CriteriaValue.TOTAL_ASSETS_MIN)) {
//                return null;
            }
            userInfoMap = new HashMap<>();
            userInfoMap.put(LoanQuotaConst.UserInfoKey.USER_ID, memberEntity.getId());//用户id
            userInfoMap.put(LoanQuotaConst.UserInfoKey.USER_RISK, risk);//信用分
            userInfoMap.put(LoanQuotaConst.UserInfoKey.TOTAL_ASSETS, totalAssets);//个人总资产
            return userInfoMap;
        } catch (Exception e) {
            log.error("获取用户信息错误： {}", e);
            return null;
        }
    }


    /*
     * Description :   用户贷款额度审核
     *                  总额度 = 基础额度 + 额外额度
     *                  基础额度 = 最低额度 *（信用分/10 + 信用等级）
     *                  额外额度 = 总资产(必须大于1000) * 0.1 / 100 * 100 (舍去百位以下)
     * ChangeLog : 1. 创建 (2021/4/17 10:04 );
     * @param userInfoMap   用户信息集合
     * @return totalQuota    总额度
     */
    private BigDecimal examineQuota (HashMap<String, Object> userInfoMap) {
        try {
            UserLoanQuotaInfo userLoanQuotaInfo = new UserLoanQuotaInfo();
            //基础额度
            int risk = (int) userInfoMap.get(LoanQuotaConst.UserInfoKey.USER_RISK); //信用分
            int riskLevel = (risk / LoanQuotaConst.CriteriaValue.RISK_MIN);//信用等级
            //信用分/10 + 信用等级
            BigDecimal riskBD = new BigDecimal(String.valueOf(riskLevel + (riskLevel << 1)));
            //额外额度
            double totalAssets = (double) userInfoMap.get(LoanQuotaConst.UserInfoKey.TOTAL_ASSETS);  //总资产
            int assets = 0;
            //总资产大于1000才会有额外额度
            if (totalAssets > 1000) {
                assets = new Double(totalAssets * 0.1).intValue();
                //舍去百位以下
                assets = assets / 100 * 100;
            }
            BigDecimal addedQuota = new BigDecimal(String.valueOf(assets));//额外额度
            //总额度 = 基础额度 + 额外额度
            BigDecimal totalQuota = LoanQuotaConst.LoanQuotaValue.LOAN_QUOTA_MIN.multiply(riskBD).add(addedQuota);
            totalQuota.setScale(2, BigDecimal.ROUND_DOWN);//保留两位小数，多余位直接舍去

            //判断总额度是否大于最高额度 -1：小于   0：等于    1：大于
            int isGreaterThanMax = totalQuota.compareTo(LoanQuotaConst.LoanQuotaValue.LOAN_QUOTA_MAX);
            if (isGreaterThanMax == - 1) {
                return totalQuota;
            } else {
                return LoanQuotaConst.LoanQuotaValue.LOAN_QUOTA_MAX;
            }
        } catch (Exception e) {
            log.error("计算额度错误：{}", e.getMessage());
            return null;
        }
    }

    /*
     * Description :    获取分期服务费
     * ChangeLog : 1. 创建 (2021/4/19 10:49 );
     * @param null
     * @return SysRateBean  分期服务费
     */
    private BigDecimal updateSysRate () {
        BigDecimal instalmentServiceRate = null; //分期服务费
        HashMap<String, SysRateBean> sysRates = null;
        try {
            //从Redis中取出系统费率
//            sysRates = (HashMap<String, SysRateBean>)valueOperations.get(SysRateConst.RedisKey.SYSTEM_RATES);

//            String sysRate1 = systemFeign.getSysRate();
//            System.out.println("sysRate1");
//            List<SysRateBean> sysRateBeans =  JSON.parseObject(
//                    JSON.parseObject(sysRate1).getString("data"), List.class);
//            for (SysRateBean sysRateBean : sysRateBeans) {
//                sysRates.
//            }
            if (sysRates != null) {
                SysRateBean sysRateBean = om.convertValue(sysRates.get(SysRateConst.RateType.INSTALMENT_SERVICE), SysRateBean.class);//数据处理,否则会报类型转换异常
                instalmentServiceRate = sysRateBean.getRate();
            } else {
                String sysRate = systemFeign.getSysRate();
                List<SysRateBean> allRate = JSON.parseArray(
                        JSON.parseObject(sysRate).getString("data"), SysRateBean.class);//系统费率
                //将新费率存入Redis以供其他模块使用
                sysRates = new HashMap<>();
                for (SysRateBean rate :
                        allRate) {
                    sysRates.put(rate.getRateType(), rate);
                }
                valueOperations.set(SysRateConst.RedisKey.SYSTEM_RATES, sysRates, 24L, TimeUnit.HOURS);
                instalmentServiceRate = sysRates.get(SysRateConst.RateType.INSTALMENT_SERVICE).getRate();
            }
        } catch (Exception e) {
            log.error("查询系统费率错误：{}", e);
        } finally {
            return instalmentServiceRate;
        }
    }
}
